#pragma once
#include <map>
#include "arrow/arrow.h"
#include "../common/common.h"
#include "i_session.h"
#include "server/session/session_machine/state_machin_define.h"
#include "session_machine/session_machine.h"

namespace ArrowWebCodeView
{

class CSession : public ISession, public std::enable_shared_from_this<CSession>
{
    using MapStroToSessisonMachineMsg = std::map<std::string, ArrowWebCodeView::SessionMachine::MsgEnum>;
public:
    CSession(asio::io_context& ioContext, tcp::socket socket, const std::string& strConnectInfo);
    virtual ~CSession();

    void Start();
private:

    void OnAccept(boost::system::error_code ec);

    void DoReadCmd();
    void OnReadCmd(boost::system::error_code errorCode, std::size_t bytesTransferred);

    void DoReadCmdData(std::string strCmd);
    void OnReadCmdData(std::string strCmd, boost::system::error_code errorCode, std::size_t bytesTransferred);

    void DoWrite(const std::string& strData);
    void OnWrite1(boost::system::error_code errorCode, std::size_t bytesTransferred);
    void OnWrite2(const std::string& strData,boost::system::error_code errorCode, std::size_t bytesTransferred);

    void Close();
private:
    asio::io_context& m_IoContext;
    websocket::stream<tcp::socket> m_WebSocket;
    beast::flat_buffer m_ReadBuffer;

    MapStroToSessisonMachineMsg m_MapStroToSessisonMachineMsg;
    ArrowWebCodeView::SessionMachine::Context m_SessionMachine;

    std::string m_strConnectInfo;
    std::string m_strMsgSrcInfo;
};

}